package com.itnoob.service;

import com.itnoob.factory.PayStrategyFactory;
import com.itnoob.strategy.PayStrategy;
import com.itnoob.type.PayTypeEnum;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;

/**
 * @author zhoujun
 * @date 2025/3/19 23:29
 */
@Service
public class PayService {
    //使用ThreadLocal来存储当前线程所选择的支付方式
    private ThreadLocal<PayTypeEnum> payTypeThreadLocal = new ThreadLocal<>();

    /**
     * 自动注入各种策略
     */

    @Resource
    private PayStrategyFactory payStrategyFactory;

    /**
     * PayService是单例的,但是线程都会共享它,如果单例的对象里面有成员变量.
     * 支付类型--主要是为了模拟线程不安全,成员变量,一个可变的成员变量,属于对象的,多个线程会共享同一个对象.
     * 所以如果不使用ThreadLocal来隔离每个线程的值，就会出现数据不一致和逻辑错误的情况。
     */
    private PayTypeEnum payTypeEnum;

    public static final String CODE_1 = "code1"; //这种就是线程安全的,因为是final修饰的,不可变对象

    public void setPayTypeEnum(PayTypeEnum payTypeEnum) {
        payTypeThreadLocal.set(payTypeEnum);  //线程安全
        this.payTypeEnum = payTypeEnum;////线程不安全
    }

    public PayTypeEnum getPayType() {
        return payTypeThreadLocal.get(); //线程安全
//        return payTypeEnum;  //线程不安全
    }

    public void pay(BigDecimal amount){
        PayTypeEnum payTypeEnum = getPayType();
        PayStrategy payStrategy = payStrategyFactory.getPayStrategy(payTypeEnum);
        System.out.println("当前线程=" + Thread.currentThread().getName() + "支付类型=" + payTypeEnum.getValue().toString() + "支付了" + amount + "元" );
        payStrategy.pay(amount);
//        remove(); //不清楚这里这里是不是在这删除threadLocal
    }


    public void remove(){
        payTypeThreadLocal.remove();
    }
}
